package utility.files;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.List;

public class TextFile {
	private File _file;
	private boolean _inAppend;
	private FileUtility _fileUtility;
	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
	private String _encoding;
	private Lines _report;

	public TextFile(String filePath, boolean inAppend) {
		this(new File(filePath), inAppend);
	}
	
	public TextFile(File file, boolean inAppend) {
		_inAppend = inAppend;
		_file = file;
		_fileUtility = new FileUtility();
		_report = new Lines();
		_encoding = "ISO-8859-1";
		//"In append" we would need to detect Encoding, but seems to be hard :O
//		if(_inAppend) _encoding = ????
	}

	public static synchronized TextFile inAppend(String filePath){
		return new TextFile(filePath, true);
	}
	
	public static synchronized TextFile inAppend(File file){
		return new TextFile(file, true);
	}
	
	public static synchronized TextFile inRewrite(String filePath){
		return new TextFile(filePath, false);
	}
	
	public static synchronized TextFile inRewrite(File file){
		return new TextFile(file, false);
	}

	public synchronized void putLine(String aLine) {
		if (!_file.exists()){
			try {
				_file.createNewFile();
			} catch (IOException e) {
			}			
		}
		StringBuffer textToWrite = new StringBuffer();
		boolean emptyFile = asText().trim().isEmpty();
		if (_inAppend&&!emptyFile)textToWrite.append(LINE_SEPARATOR);
		textToWrite.append(aLine);			
		writeOnUsing(textToWrite.toString(), _file, _inAppend, _encoding);		
		_inAppend = true; // Yes: first time we could decide to rewrite, but then the previous "putLines" must remain.
	}

	public static void writeOnUsing(String text, File aFile, boolean inAppend, String encoding) {
		FileUtility fileUtility = new FileUtility();
		FileOutputStream outStream = null;
		try{
			byte[] bytes = text.getBytes(encoding);
			outStream = new FileOutputStream(aFile, inAppend);	
			fileUtility.writeUsing(bytes, outStream);
		} catch (IOException e) {
		}
		finally {
			fileUtility.close(outStream);
		}
		
	}

	public String asText() {
		FileInputStream fileInStream = null;
		InputStreamReader inStream = null;
		StringBuffer result = new StringBuffer();
		try {
			fileInStream = new FileInputStream(_file);
			inStream = new InputStreamReader(fileInStream, Charset.forName(_encoding));
			char[] buf = new char[1024];
			int len;
			while ((len = inStream.read (buf)) > 0)
				result.append(buf, 0, len);
		} catch (FileNotFoundException e) {
			_report.putLine("File Not Found!");
		} catch (IOException e) {
			_report.putLine("IO Exception reading from File");
		}
		finally{
			_fileUtility.close(inStream);
			_fileUtility.close(fileInStream);
		}

		return result.toString();
	}

	

	public Lines asLines() {
		String result = asText();
		Lines lines = Lines.from(result,LINE_SEPARATOR);		
		return lines;
	}


	public Lines report() {
		Lines report = _fileUtility.report();
		report.mergeWith(_report);
		return report;
	}
	
	public void setEncoding(String encoding){
		_encoding = encoding;
	}

	public synchronized void put(Lines lines) {
		List<String> linesList = lines.asList();		
		for (String each : linesList)  putLine(each);		
	}

	public String encoding() {
		return _encoding;
	}

	public void setRewrite() {
		_inAppend = false;
	}

}
